package com.world.system.service.strategy;

import cn.hutool.core.io.IoUtil;
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.world.common.exception.GlobalException;
import com.world.common.utils.FileUtil;
import com.world.system.domain.SysOssFile;
import com.world.system.domain.dto.OssFileDto;
import com.world.system.service.OssStrategy;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * @Author: LiJunXi
 * @Description:
 * @Date: 2024-11-12  17:56
 */
@Slf4j
@Service
public class MinioStrategy implements OssStrategy {

    @Autowired
    private MinioClient minioClient;

    @Value("${oss.minio.bucketName}")
    private String bucketName;


    @Override
    public void saveFile(OssFileDto fileDto) {
        String extension = FileUtil.getFileExtension(fileDto.getFilename());
        String filePath = getFilePath(extension, fileDto.getFileMd5());
        fileDto.setFilePath(filePath);
        try {
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .object(filePath)
                    .bucket(bucketName)
                    .stream(new ByteArrayInputStream(fileDto.getFileData()), fileDto.getFileData().length, -1)
                    .contentType(getMimeType(extension))
                    .build();
            minioClient.putObject(putObjectArgs);
        } catch (Exception e) {
            log.error("上传文件出错，原因：{}", e.getMessage());
           throw new GlobalException("上传文件出错");
        }
    }

    @Override
    public byte[] getFile(SysOssFile fileEntity) {
        String filePath = fileEntity.getFilePath();
        try {
            InputStream inputStream = minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(filePath)
                            .build());
            return IoUtil.readBytes(inputStream);
        } catch (Exception e) {
            log.error("下载文件出错，原因：{}", e.getMessage());
            throw new GlobalException("下载文件出错");
        }
    }

    @Override
    public void deleteFile(SysOssFile fileEntity) {
        String filePath = fileEntity.getFilePath();
        try {
            RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object(filePath)
                    .build();
            minioClient.removeObject(removeObjectArgs);
        } catch (Exception e){
            log.error("删除文件出错，原因：{}", e.getMessage());
            throw new GlobalException("删除文件出错");
        }
    }

    public String getMimeType(String extension) {
        if (Objects.isNull(extension)){
            extension = "";
        }
        ContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);
        String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;  // 通用mimeType，字节流
        if (Objects.nonNull(extensionMatch)){
            mimeType = extensionMatch.getMimeType();
        }
        return mimeType;
    }

    private String getFilePath(String extension, String fileMd5){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String absolutePath = sdf.format(new Date()).replace("-", "/");
        return absolutePath + '/' + fileMd5 + "." + extension;
    }
}
